package services;

import java.util.Collection;
import java.util.Date;
import java.util.HashSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import repositories.RegistrationRepository;

import domain.Project;
import domain.Registration;
import domain.User;
import domain.Vacancy;
import domain.WorkUpdate;

@Service
@Transactional
public class RegistrationService {
	
	//Managed Repository
	@Autowired
	private RegistrationRepository registrationRepository;
	
	//Supporting Services
	@Autowired
	private UserService userService;
	
	@Autowired
	private ProjectService projectService;
	
	@Autowired
	private VacancyService vacancyService;
	
	//Constructors

	public RegistrationService() {
		super();
	}
	
	//Simple CRUD methods
	public Registration create(Project project) {
		User user;
		Date currentMoment;
		Registration alreadyRegistered;
		Registration registration;
		Collection<WorkUpdate> workUpdates;
		
		Assert.notNull(project);
		currentMoment = new Date(System.currentTimeMillis()-60000);
		user = userService.findByPrincipal();
		workUpdates = new HashSet<WorkUpdate>();
		alreadyRegistered = getRegistrationForProject(user.getId(), project.getId());
		Assert.isNull(alreadyRegistered);
		
		registration = new Registration();
		registration.setUser(userService.findByPrincipal());
		registration.setRegistrationMoment(currentMoment);
		registration.setProject(project);
		registration.setWorkUpdates(workUpdates);
		registration.setTotalAmountOfWork(0.0);
		return registration;
	}

	public void save(Registration registration) {
		Assert.notNull(registration);
		Project project;
		Vacancy vacancy;
		Collection<Vacancy> vacancies;
		int cont;
		
		project = registration.getProject();
		if(registration.getId()==0){
			Assert.isTrue(registration.getUser().equals(userService.findByPrincipal()));
			Collection <Project> projects = projectService.findAvailableProjects();
			Assert.isTrue(projects.contains(project));
		}
		
		vacancy = vacancyService.findByProjectAndGroupId(project.getId(), userService.findByPrincipal().getUserGroup().getId());
		if(vacancy.getPeopleRequired()>0){
			vacancy.setPeopleRequired(vacancy.getPeopleRequired()-1);
		}
		//Recruiting->Started
		if(vacancy.getPeopleRequired() == 0){
			cont = 0;
			vacancies = project.getVacancies();
			
			for(Vacancy v: vacancies){
				if(v.getPeopleRequired()!=0){cont++;}
			}
			if(cont == 0){project.setStatus("Started");}
		}
		
		registrationRepository.save(registration);
	}
	
	public Registration findOne(int registrationId) {

		Assert.isTrue(registrationId != 0);
		Registration result;
		result = registrationRepository.findOne(registrationId);
		Assert.notNull(result);

		return result;
	}
	
	public Collection<Registration> findAll(){
		Collection<Registration> result;
		
		result = registrationRepository.findAll();
		
		return result;
	}
	//Other Business Methods

	public Collection<Registration> findByProjectId(int projectId){
		Collection<Registration> result;
		result = registrationRepository.findByProjectId(projectId);
		Assert.notNull(result);
		
		return result;
	}
	
	public Registration getRegistrationForProject(int userId, int projectId) {
		Assert.isTrue(userId != 0 && projectId != 0);
		Registration result = registrationRepository.IsRegisteredForProject(
				userId, projectId);
		return result;

	}

	public Boolean IsRegisteredForProject(int userId, int projectId) {
		Assert.isTrue(userId != 0 && projectId != 0);
		Registration result = registrationRepository.IsRegisteredForProject(
				userId, projectId);

		Boolean registered = false;
		if (result != null) {
			registered = true;
		}

		return registered;

	}



}
